home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Risc World 3
/
Risc World 3.iso
/
SOFTWARE
/
ISSUE6
/
PD
/
PDF
/
pdf
/
c++
/
FileInfo
< prev
next >
Wrap
Text File
|
2003-02-14
|
12KB
|
374 lines
//--------------------------------------------------------------------------
//
// Copyright (c) 2002, Colin Granville
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// * The name Colin Granville may not be used to endorse or promote
// products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//--------------------------------------------------------------------------
#include "FileInfo.h"
#include "GuiWindow.h"
#include "PDFDoc.h"
#include "GuiTargets.h"
#include "Object.h"
#include "dict.h"
#include <time.h>
#include "file.h"
#include "strstream.h"
#include <math.h>
#include "DrawOutputFont.h"
#include <iomanip.h>
#include "guilib:gfx.h"
//******************************************************************************
class FileInfoFont
{
public:
FileInfoFont(const char* name,int size,int height);
~FileInfoFont();
int getHandle() {return handle;}
private:
int handle;
};
//******************************************************************************
FileInfoFont::FileInfoFont(const char* name,int size,int height)
: handle(0)
{
_swix(Font_FindFont,_INR(1,5)|_OUT(0),name,size,height,0,0,&handle);
}
//******************************************************************************
FileInfoFont::~FileInfoFont()
{
if (handle) _swix(Font_LoseFont,_IN(0),handle);
}
//******************************************************************************
class FileInfo
{
public:
FileInfo();
void setData(const FileInfoData& d);
private:
GuiWindow window;
const FileInfoData* data;
GUI_DECLARE_EVENT_TARGETS(FileInfo);
GuiWimpTarget redrawWindowTarget;
Claim redrawWindow(GuiWimpPollBlock&,const GuiIdBlock&);
GuiToolboxTarget hasBeenHiddenTarget;
Claim hasBeenHidden(GuiToolboxEvent&,const GuiIdBlock&);
};
//******************************************************************************
FileInfo::FileInfo()
: window("FileInfo"),
redrawWindowTarget(&window,GuiWimp_ERedrawWindow,this,FileInfo::redrawWindow),
hasBeenHiddenTarget(&window,GuiWindow::HasBeenHidden::Event,this,FileInfo::hasBeenHidden)
{
}
//*************************************************************************
Claim FileInfo::hasBeenHidden(GuiToolboxEvent&,const GuiIdBlock&)
{
GuiGetWindowStateBlock ws;
window.getState(ws);
ws.xscroll=0;
ws.yscroll=0;
ws.visibleArea.setWidth(868);
ws.visibleArea.setHeight(264);
// Resize window.
// Can't use toolbox as it calls events.
// The window isn't actually displayed.
// Can't resize before showing because
// it opens on a menu
_swix(Wimp_OpenWindow,_IN(1),&ws);
_swix(Wimp_CloseWindow,_IN(1),&ws);
return CLAIM;
}
//*************************************************************************
void getMaxWidth(FileInfoFont& font,const string& s,int& maxwid)
{
int wid;
_swix(Font_ScanString,_INR(0,5) | _OUT(3),font.getHandle(),s.c_str(),(1<<8),-1,-1,0,&wid);
if (wid>maxwid) maxwid=wid;
}
//*************************************************************************
void FileInfo::setData(const FileInfoData& d)
{
data=&d;
FileInfoFont base("Homerton.medium",12*16,12*16);
int maxwid=320;
getMaxWidth(base,data->filename,maxwid);
getMaxWidth(base,data->title,maxwid);
getMaxWidth(base,data->subject,maxwid);
getMaxWidth(base,data->keywords,maxwid);
getMaxWidth(base,data->author,maxwid);
getMaxWidth(base,data->creator,maxwid);
getMaxWidth(base,data->producer,maxwid);
getMaxWidth(base,data->creationDate,maxwid);
getMaxWidth(base,data->modDate,maxwid);
getMaxWidth(base,data->pages,maxwid);
getMaxWidth(base,data->pageSize,maxwid);
getMaxWidth(base,data->fileSize,maxwid);
getMaxWidth(base,data->tagged,maxwid);
getMaxWidth(base,data->permissions,maxwid);
getMaxWidth(base,data->optimised,maxwid);
getMaxWidth(base,data->pdfVersion,maxwid);
maxwid/=400;
GuiBBox box;
window.getExtent(box);
box.setWidth(8+224+maxwid+20);
window.setExtent(box);
}
//*************************************************************************
#define FI_HEIGHT 40
bool showLine(int x,int &y,FileInfoFont& bold,const char* name,
FileInfoFont& base,const string& value,
GuiRedrawWindowBlock& block)
{
y-=FI_HEIGHT;
if (y+FI_HEIGHT <= block.redrawArea.ymin) return 0;
if (y < block.redrawArea.ymax)
{
int wid;
_swix(Font_ScanString,_INR(0,5) | _OUT(3),bold.getHandle(),name,(1<<8),-1,-1,0,&wid);
int offset=200*400-wid;
_swix(ColourTrans_SetFontColours,_INR(0,3),bold.getHandle(),0xdddddd00,0,14);
_swix(Font_Paint,_INR(0,7),bold.getHandle(),name,(1<<8),x*400+offset,y*400+FI_HEIGHT*400*5/16,0,0,0);
_swix(ColourTrans_SetFontColours,_INR(0,3),base.getHandle(),0xdddddd00,0,14);
_swix(Font_Paint,_INR(0,7),base.getHandle(),(value.size()?value.c_str():"--"),(1<<8),
(x+224+8)*400,y*400+FI_HEIGHT*400*5/16,0,0,0);
}
return 1;
}
//*************************************************************************
Claim FileInfo::redrawWindow(GuiWimpPollBlock& wpb,const GuiIdBlock&)
{
bool more;
GuiRedrawWindowBlock& block=wpb.redrawWindowRequest;
FileInfoFont base("Homerton.medium",12*16,12*16);
FileInfoFont bold("Homerton.bold",12*16,12*16);
for (GuiWindow::redraw(block,more);more;GuiWindow::getRectangle(block,more))
{
if (data)
{
int x=block.xToScreen(8);
int y=block.yToScreen(-8);
gfx::gcol_bgr(0,0xdddddd00);
gfx::rectanglefill(block.xToScreen(224),block.yToScreen(-1280),1280,1280);
gfx::gcol_bgr(0,0x99999900);
gfx::rectanglefill(block.xToScreen(224-4),block.yToScreen(-1280),2,1280);
gfx::gcol_bgr(0,0xffffff00);
gfx::rectanglefill(block.xToScreen(224),block.yToScreen(-1280),2,1280);
if (!showLine(x,y,bold,"Title",base,data->title,block)) break;
if (!showLine(x,y,bold,"Subject",base,data->subject,block)) break;
if (!showLine(x,y,bold,"Keywords",base,data->keywords,block)) break;
y-=12;
if (!showLine(x,y,bold,"Author",base,data->author,block)) break;
if (!showLine(x,y,bold,"Creator",base,data->creator,block)) break;
if (!showLine(x,y,bold,"Producer",base,data->producer,block)) break;
y-=12;
if (!showLine(x,y,bold,"Creation Date",base,data->creationDate,block)) break;
if (!showLine(x,y,bold,"Mod Date",base,data->modDate,block)) break;
y-=12;
if (!showLine(x,y,bold,"Pages",base,data->pages,block)) break;
if (!showLine(x,y,bold,"Page size",base,data->pageSize,block)) break;
y-=12;
if (!showLine(x,y,bold,"File name",base,data->filename,block)) break;
if (!showLine(x,y,bold,"File size",base,data->fileSize,block)) break;
if (!showLine(x,y,bold,"Access",base,data->permissions,block)) break;
y-=12;
if (!showLine(x,y,bold,"Tagged",base,data->tagged,block)) break;
if (!showLine(x,y,bold,"Optimised",base,data->optimised,block)) break;
if (!showLine(x,y,bold,"PDF Version",base,data->pdfVersion,block)) break;
}
}
return CLAIM;
}
//*************************************************************************
string getInfo(PDFDoc& doc,const char* key)
{
string res;
Object info;
Object obj;
doc.getDocInfo(&info);
if (info.isDict()) info.dictLookup((char*)key, &obj);
if (obj.isString())
res=toAcornLatin1(obj.getString()->getCString(),
obj.getString()->getLength());
obj.free();
info.free();
return res;
}
//*************************************************************************
string getInfoDate(PDFDoc& doc, const char* key)
{
string res;
Object info;
Object obj;
doc.getDocInfo(&info);
if (info.isDict()) info.dictLookup((char*)key, &obj);
if (obj.isString())
{
char* s=obj.getString()->getCString();
if (s[0] == 'D' && s[1] == ':') s += 2;
struct tm tmStruct;
if (sscanf(s, "%4d%2d%2d%2d%2d%2d", &tmStruct.tm_year,
&tmStruct.tm_mon,
&tmStruct.tm_mday,
&tmStruct.tm_hour,
&tmStruct.tm_min,
&tmStruct.tm_sec)==6)
{
tmStruct.tm_year-= 1900;
tmStruct.tm_mon-= 1;
tmStruct.tm_wday = -1;
tmStruct.tm_yday = -1;
tmStruct.tm_isdst = -1;
mktime(&tmStruct); // compute the tm_wday and tm_yday fields
char buf[256];
if (strftime(buf, sizeof(buf), "%c", &tmStruct))
res=buf;
else
res=s;
}
else res=s;
}
obj.free();
info.free();
return res;
}
//*************************************************************************
void FileInfo_create(FileInfoData& data ,PDFDoc& doc,const string& filename)
{
data.filename=filename;
data.title=getInfo(doc,"Title");
data.subject=getInfo(doc,"Subject");
data.keywords=getInfo(doc,"Keywords");
data.author=getInfo(doc,"Author");
data.creator=getInfo(doc,"Creator");
data.producer=getInfo(doc,"Producer");
data.creationDate=getInfoDate(doc,"CreationDate");
data.modDate=getInfoDate(doc,"ModDate");
data.tagged=(doc.getStructTreeRoot()->isDict() ? "yes" : "no");
char buf[256];
ostrstream out(buf,256);
out << doc.getNumPages();
data.pages=out.str();
out.seekp(0);
out << "Print:" << (doc.okToPrint(gTrue) ? "yes " : "no ");
out << "Copy:" << (doc.okToCopy(gTrue) ? "yes " : "no ");
out << "Modify:" << (doc.okToChange(gTrue) ? "yes " : "no ");
out << "Add notes:" << (doc.okToAddNotes(gTrue) ? "yes" : "no");
data.permissions=out.str();
// get page size
if (doc.getNumPages() >= 1)
{
out.seekp(0);
double w,h;
w = doc.getPageWidth(1);
h = doc.getPageHeight(1);
out.setf(ios::fixed);
out << setprecision(1) << w*25.4/72<< " x " << h*25.4/72 << " mm";
if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
(fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1))
{
out << " (letter)";
}
else if ((fabs(w - 595) < 0.1 && fabs(h - 842) < 0.1) ||
(fabs(w - 842) < 0.1 && fabs(h - 595) < 0.1))
{
out << " (A4)";
}
data.pageSize=out.str();
}
out.seekp(0);
int len;
if (isFile(filename.c_str(),0,&len))
{
out << len << " bytes";
data.fileSize=out.str();
}
data.optimised=(doc.isLinearized() ? "yes" : "no");
out.seekp(0);
out << doc.getPDFVersion();
data.pdfVersion=out.str();
}
//******************************************************************************
void FileInfo_ATBS(const FileInfoData& data)
{
static FileInfo info;
info.setData(data);
}